package com.yupi.springbootinit.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessage;
import com.volcengine.ark.runtime.model.completion.chat.ChatMessageRole;
import com.yupi.springbootinit.common.ErrorCode;
import com.yupi.springbootinit.exception.BusinessException;
import com.yupi.springbootinit.manager.BigModelHuoShan;
import com.yupi.springbootinit.mapper.ChatMessagesMapper;
import com.yupi.springbootinit.model.entity.ChatMessages;
import com.yupi.springbootinit.model.entity.ChatRoom;
import com.yupi.springbootinit.model.entity.User;
import com.yupi.springbootinit.service.ChatMessageService;
import com.yupi.springbootinit.service.ChatRoomService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import static com.yupi.springbootinit.constant.ChatConstant.SYSTEM_PROMPT;
import static com.yupi.springbootinit.constant.UserConstant.USER_LOGIN_STATE;

/**
* @author 尔特岛
* @description 针对表【chatmessage(聊天消息表)】的数据库操作Service实现
* @createDate 2025-03-27 16:22:41
*/
@Service
@Slf4j
public class ChatMessageServiceImpl extends ServiceImpl<ChatMessagesMapper, ChatMessages> implements ChatMessageService {


    @Resource
    private BigModelHuoShan bigModelHuoShan;

    @Resource
    @Lazy
    private ChatRoomService chatRoomService;

    private int MAX_SIZE = 5;

    long startTime = System.currentTimeMillis();  //每隔10min,自动写入数据库

    //存储历史记录
    private Map<String, List<ChatMessage>> chatMessageHistory = new HashMap<>();

    //批量写输入数据库
    List<ChatMessages> chatMessagesList = new ArrayList<>();

    /**
     * AI对话核心方法 (内存存储版
     * @param request
     * @param roomId
     * @param userPrompt
     * @return
     */
    @Override
    public String doChatOfIM(HttpServletRequest request, String roomId, String userPrompt) {
        //准备消息关联上下文
        final String systemPrompt = SYSTEM_PROMPT;
        final ChatMessage SystemMessage = ChatMessage.builder().role(ChatMessageRole.SYSTEM).content(systemPrompt).build();
        final ChatMessage userMessage = ChatMessage.builder().role(ChatMessageRole.USER).content(userPrompt).build();

        //处理历史对话历史记录
        List<ChatMessage> messages = new ArrayList<>();
        if(!"开始".equals(userPrompt) && chatMessageHistory.isEmpty()){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"请输入“开始”，开启游戏");
        }
        //第一次用户输入信息
        if("开始".equals(userPrompt) && !chatMessageHistory.containsKey(roomId)){
            messages.add(SystemMessage);
            chatMessageHistory.put(roomId,messages);
        }else{
//            第1+n次输入信息,添加历史记录
            messages = chatMessageHistory.get(roomId);
        }
        messages.add(userMessage);
        //调用AI
        String response = bigModelHuoShan.doChat(messages);

        final ChatMessage assistantMessage = ChatMessage.builder().role(ChatMessageRole.ASSISTANT).content(response).build();
        messages.add(assistantMessage);

        //清除map缓存
        if(response.contains("【游戏已结束】")){
            chatMessageHistory.remove(roomId);
        }
        //返回结果
        return response;
    }

    /**
     * AI对话核心方法 (数据库版   批量写入
     * todo 修改 封装ai返回的对象
     * @param request
     * @param roomId
     * @param userPrompt
     * @return
     */
    @Override
    public String doChatOfDB(HttpServletRequest request, String roomId, String userPrompt) {
        //准备消息关联上下文
        final String systemPrompt = SYSTEM_PROMPT;
        final ChatMessage SystemMessage = ChatMessage.builder().role(ChatMessageRole.SYSTEM).content(systemPrompt).build();
        final ChatMessage userMessage = ChatMessage.builder().role(ChatMessageRole.USER).content(userPrompt).build();

        User user = (User)request.getSession().getAttribute(USER_LOGIN_STATE);
        if(user == null || user.getId() == null){
            throw new BusinessException(ErrorCode.NOT_LOGIN_ERROR);
        }
        Long userId = user.getId();
        //处理历史对话历史记录
        List<ChatMessage> messages = new ArrayList<>();

        LambdaQueryWrapper<ChatMessages> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(ChatMessages::getRoomId,roomId);
        List<ChatMessages> list = this.list(queryWrapper);

        if(!"开始".equals(userPrompt.trim()) && chatMessageHistory.isEmpty()){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"请输入“开始”，开启游戏");
        }
        //第一次用户输入信息
        if("开始".equals(userPrompt) && list.isEmpty()){
            messages.add(SystemMessage);
            chatMessageHistory.put(roomId,messages);

        }else{
//            第1+n次输入信息,添加历史记录
            messages = chatMessageHistory.get(roomId);
        }
        messages.add(userMessage);
        //调用AI
        String response = bigModelHuoShan.doChat(messages);

        //第一次用户输入信息
        if("开始".equals(userPrompt) && list.isEmpty()){
            //房间ID写入库
            ChatRoom chatRoom = new ChatRoom();
            chatRoom.setId(Long.parseLong(roomId));
            chatRoom.setUserId(userId);
            chatRoom.setRoomBrief(response);
            chatRoomService.save(chatRoom);
        }

        final ChatMessage assistantMessage = ChatMessage.builder().role(ChatMessageRole.ASSISTANT).content(response).build();
        messages.add(assistantMessage);

        //每次请求存储用户 和 AI的消息
        ChatMessages chatMessagesUser = new ChatMessages();
        chatMessagesUser.setRoomId(roomId);
        chatMessagesUser.setContent(userPrompt);
        chatMessagesUser.setSender("USER");
        ChatMessages chatMessagesAI = new ChatMessages();
        chatMessagesAI.setRoomId(roomId);
        chatMessagesAI.setContent(response);
        chatMessagesAI.setSender("AI");

        chatMessagesList.add(chatMessagesUser);
        chatMessagesList.add(chatMessagesAI);
        //当消息存储到一定阈值 或者 会话超时 或者，游戏结束 则开始批量存入数据库，
        if(chatMessagesList.size() > MAX_SIZE || isTimeout(startTime) || response.contains("【游戏已结束】")){
            if(!this.saveBatch(chatMessagesList)) {
                log.info("消息保存失败");
                 throw new BusinessException(ErrorCode.SYSTEM_ERROR);
            }
            //重置会话开始时间
            startTime = System.currentTimeMillis();
            chatMessagesList.clear();
        }
        //清除map缓存
        if(response.contains("【游戏已结束】")){
            chatMessageHistory.remove(roomId);
            //设置房间状态
            ChatRoom chatRoom = new ChatRoom();
            chatRoom.setId(Long.parseLong(roomId));
            chatRoom.setStatus(0);
            chatRoomService.updateById(chatRoom);
        }

        return response;
    }


    /**
     * AI对话核心方法 (数据库版   -redis,MQ结合写入
     * * @param request
     * @param roomId
     * @param userPrompt
     * @return
     */
    @Override
    public String doChat(HttpServletRequest request, String roomId, String userPrompt) {
        return null;
    }


    public boolean isTimeout(long startTime){
        long timeOut = 1000 * 10 * 60L; //10min
        if(System.currentTimeMillis() - startTime > timeOut){
            log.error("会话超时,消息自动存入数据库");
            return true;
        }
        return false;
    }
}

//todo 优化
//当用户突然离开聊天框 死机，切屏，如何保证聊天记录即使被保存  mq
//todo 当房间没有活动,超过某一时间后，自动结束，修改房间状态自动为0
//todo  chatMessageHistory 由redis做存储
//分库分表，对每个房间消息做隔离


